#pragma once

#include "LeGraphics.h"

#include <QBrush>
#include <QMap>

class LEGRAPHICSVIEW_EXPORT LeGraphicsFeatureOption
{
public:
    LeGraphicsFeatureOption()
    {
        // FIXME: replace with generic name, and let upper layer redefine
        // their anonymous enum on top of them. eg.:
        // ns LeGraphics { enum { Feature1 = 0, ..., FeatureCount} }
        // ns MyApp { enum { PadFeature = LeGraphics::Feature1, ... } }
        m_visibilityMap = {
            {GftPad, false},
            {GftPin, false},
            {GftFiducial, false},
            {GftHole, false},
            {GftSlot, false},
            {GftFill, false},
            {GftTrace, false},
            {GftText, false},
        };
        m_brushMap = {
            {GftPad, QBrush()},
            {GftPin, QBrush()},
            {GftFiducial, QBrush()},
            {GftHole, QBrush()},
            {GftSlot, QBrush()},
            {GftFill, QBrush()},
            {GftTrace, QBrush()},
            {GftText, QBrush()},
        };
    }

    LeGraphicsFeatureOption(const LeGraphicsFeatureOption &other) { *this = other; }
    ~LeGraphicsFeatureOption() {}

    LeGraphicsFeatureOption& operator=(const LeGraphicsFeatureOption& rhs)
    {
        if (this != &rhs)
        {
            m_visibilityMap = rhs.m_visibilityMap;
            m_brushMap = rhs.m_brushMap;
        }
        return *this;
    }

    inline void setAllFeatureVisible(bool visible)
    {
        for (auto key: m_visibilityMap.keys())
            m_visibilityMap[key] = visible;
    }

    inline void setFeatureVisible(LeGraphicsFeature type, bool visible)
    {
        m_visibilityMap[type] = visible;
    }

    inline bool isFeatureVisible(LeGraphicsFeature type) const
    {
        return m_visibilityMap.value(type);
    }

    inline void setAllFeatureBrush(const QBrush &brush)
    {
        for (auto key: m_brushMap.keys())
            m_brushMap[key] = brush;
    }

    inline void setFeatureBrush(LeGraphicsFeature type, const QBrush &brush)
    {
        m_brushMap[type] = brush;
    }

    inline QBrush featureBrush(LeGraphicsFeature type) const
    {
        return m_brushMap.value(type);
    }

private:
    QMap<LeGraphicsFeature, bool> m_visibilityMap;
    QMap<LeGraphicsFeature, QBrush> m_brushMap;
    friend bool operator==(const LeGraphicsFeatureOption& lhs, const LeGraphicsFeatureOption& rhs);
};

inline bool operator==(const LeGraphicsFeatureOption& lhs, const LeGraphicsFeatureOption& rhs)
{
    return lhs.m_brushMap == rhs.m_brushMap &&
            lhs.m_visibilityMap == rhs.m_visibilityMap;
}

inline bool operator!=(const LeGraphicsFeatureOption& lhs, const LeGraphicsFeatureOption& rhs)
{
    return !(lhs == rhs);
}
